/**
 * 
 */
package appStarshipPushups.client.form;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import appStarshipPushups.client.model.Connection;
import appStarshipPushups.client.model.ConnectionException;

/**
 * @author Adam Labranche
 */
public class AppFrame extends JFrame implements WindowListener
{
	public static final long serialVersionUID = 1L;
	private static final int WINDOW_WIDTH = 800;
	private static final int WINDOW_HEIGHT = 600;
	private static final String WINDOW_TITLE = "Starship Pushup's 2";
	private static final Color COLOR_BG = Color.black;
		
	/**
	 * Cette constante contient la question posée lors de la demande de
	 * confirmation de quitter du joueur.
	 */
	private static final String DEFAULT_EXIT_QUESTION = "Êtes-vous certain de vouloir quitter?";
	/**
	 * Cette constante contient le titre de la boîte de dialogue de demande
	 * de confirmation.
	 */
	private static final String DEFAULT_EXIT_TITLE = "Confirmation";
	
	/**
	 * Ce membre représente la barre de menu du jeu.
	 */
	private AppMenu mainMenu = new AppMenu();
	/**
	 * Ce membre statique représente l'instance de la fenêtre du jeu.
	 */
	private static AppFrame myFrame = null;
	/**
	 * Ce membre représente le panneau de l'interface dans laquelle le joueur
	 * joue.
	 */
	private GamePanel gamePanel = new GamePanel();
	
	/**
	 * C'est le constructeur par défaut.
	 */
	private AppFrame()
	{
		super();
		this.init();
	}
	
	/**
	 * Cette fonction initialise l'interface de la fenêtre principale.
	 */
	private void init()
	{
		this.setLayout(new GridBagLayout());
		this.setSize(AppFrame.WINDOW_WIDTH, AppFrame.WINDOW_HEIGHT);
		this.setResizable(false);
		this.setTitle(AppFrame.WINDOW_TITLE);
		this.setBackground(AppFrame.COLOR_BG);
		this.getContentPane().setBackground(AppFrame.COLOR_BG);
		
		this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		
		// On centre la fenêtre dans l'écran de l'utilisateur.
		this.setLocation((int)(Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - AppFrame.WINDOW_WIDTH / 2),
				(int)(Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - AppFrame.WINDOW_HEIGHT / 2));
		
		// On initialise le WindowListener pour pouvoir faire une demande de
		// confirmation à l'utilisateur lorsqu'il ferme la fenêtre.
		this.addWindowListener(this);
				
		this.add(this.gamePanel, new GridBagConstraints());
		
		this.setJMenuBar(this.mainMenu);
	}
	
	/**
	 * Cette fonction permet d'obtenir le singleton de la classe AppFrame.
	 * @return Retourne le singleton de AppFrame.
	 */
	public static AppFrame getInstance()
	{
		if(AppFrame.myFrame == null)
		{
			AppFrame.myFrame = new AppFrame();
		}
		return AppFrame.myFrame;
	}

	/**
	 * Cette fonction permet d'obtenir le panneau d'interface dans lequel
	 * le joueur joue.
	 * @return Le panneau de jeu.
	 */
	public GamePanel getGamePanel()
	{
		return this.gamePanel;
	}
	
	/**
	 * Affiche la boîte de dialogue demandant la confirmation pour quitter
	 * le jeu.
	 */
	public void askExitConfirmation()
	{
    	int answer = JOptionPane.showConfirmDialog(this, AppFrame.DEFAULT_EXIT_QUESTION, 
    			AppFrame.DEFAULT_EXIT_TITLE, JOptionPane.YES_NO_OPTION);
    	if(answer == JOptionPane.YES_OPTION)
    	{
			if(this.gamePanel.getIsGameStarted())
			{
    			try
    			{
    				Connection.getInstance().sendQuit();
    			}
    			catch(ConnectionException e)
    			{
    				System.err.println(e.getMessage());
    			}
			}
    			this.dispose();
    			System.exit(0);
    	}
	}
	
	/**
	 * Cette fonction permet d'obtenir la barre de menu du jeu.
	 * @return Le barre de menu.
	 */
	public AppMenu getMenu()
	{
		return this.mainMenu;
	}
	
    /**
     * Invoked the first time a window is made visible.
     */
    public void windowOpened(WindowEvent e){}

    /**
     * Invoked when the user attempts to close the window
     * from the window's system menu.
     */
    public void windowClosing(WindowEvent e)
    {
    	this.askExitConfirmation();
    }

    /**
     * Invoked when a window has been closed as the result
     * of calling dispose on the window.
     */
    public void windowClosed(WindowEvent e){}

    /**
     * Invoked when a window is changed from a normal to a
     * minimized state. For many platforms, a minimized window 
     * is displayed as the icon specified in the window's 
     * iconImage property.
     * @see java.awt.Frame#setIconImage
     */
    public void windowIconified(WindowEvent e){}

    /**
     * Invoked when a window is changed from a minimized
     * to a normal state.
     */
    public void windowDeiconified(WindowEvent e){}

    /**
     * Invoked when the Window is set to be the active Window. Only a Frame or
     * a Dialog can be the active Window. The native windowing system may
     * denote the active Window or its children with special decorations, such
     * as a highlighted title bar. The active Window is always either the
     * focused Window, or the first Frame or Dialog that is an owner of the
     * focused Window.
     */
    public void windowActivated(WindowEvent e){}

    /**
     * Invoked when a Window is no longer the active Window. Only a Frame or a
     * Dialog can be the active Window. The native windowing system may denote
     * the active Window or its children with special decorations, such as a
     * highlighted title bar. The active Window is always either the focused
     * Window, or the first Frame or Dialog that is an owner of the focused
     * Window.
     */
    public void windowDeactivated(WindowEvent e){}
}
